package dormouse.vfs.metadata;

import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.vfs2.FileObject;
import org.apache.poi.hpsf.Property;
import org.apache.poi.hpsf.PropertySetFactory;
import org.apache.poi.hpsf.SummaryInformation;
import org.apache.poi.poifs.eventfilesystem.POIFSReader;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;

/**
 * This class reads the metadata from an Microsoft Office file.
 * 
 */
public class MicrosoftOfficeMetadataReader extends AbstractMetaDataReader implements IMetadataReader {
    
	/**
	 * Constructor
	 * @param exts
	 */
    public MicrosoftOfficeMetadataReader() {
		setFileExtensions(new String[]{"doc","ppt","xls"});
	}


    @Override
    public Map<String, String> getMetadata(FileObject file) throws IOException{
    	POIFSReader r = new POIFSReader();
        r.registerListener(new MyPOIFSReaderListener(this.metadata),
                           "\005SummaryInformation");
        r.read(file.getContent().getInputStream());
        
        return this.metadata;
    }

    
    static class MyPOIFSReaderListener implements POIFSReaderListener
    {
    	public static final String PAGE_COUNT = "Page Count";
		public static final String LAST_PRINTED = "Last Printed";
		public static final String WORD_COUNT = "Word Count";
		public static final String LAST_SAVED_DATE = "Last Saved Date";
		public static final String CREATED_DATE = "Created Date";
		public static final String SUBJECT = "Subject";
		public static final String REVISION = "Revision";
		public static final String KEYWORDS = "Keywords";
		public static final String COMMENTS = "Comments";
		private static final String LAST_AUTHOR = "Last Author";
		public static final String AUTHOR = "Author";
		public static final String TITLE = "Title";
		Map<String, String> metadata = null;
    	
    	/**
    	 * Constructor
    	 * @param metadata
    	 */
    	public MyPOIFSReaderListener(Map<String, String> metadata){
    		this.metadata = metadata;
    	}
    	
    	/**
    	 * {@inheritDoc}
    	 */
        public void processPOIFSReaderEvent(POIFSReaderEvent event)
        {
            SummaryInformation si = null;
            try
            {
                si = (SummaryInformation)
                     PropertySetFactory.create(event.getStream());
                
                this.metadata.put(TITLE, si.getTitle());
                this.metadata.put(AUTHOR, si.getAuthor());
                this.metadata.put(LAST_AUTHOR, si.getLastAuthor());
                this.metadata.put(COMMENTS, si.getComments());
                this.metadata.put(KEYWORDS, si.getKeywords());
                this.metadata.put(REVISION, si.getRevNumber());
                this.metadata.put(SUBJECT, si.getSubject());
                this.metadata.put(CREATED_DATE, translateDate(si.getCreateDateTime()));
                this.metadata.put(LAST_SAVED_DATE, translateDate(si.getLastSaveDateTime()));
                this.metadata.put(WORD_COUNT, String.valueOf(si.getWordCount()));
                this.metadata.put(LAST_PRINTED, translateDate(si.getLastPrinted()));
                this.metadata.put(PAGE_COUNT, String.valueOf(si.getPageCount()));
                
                addProperties(this.metadata, si.getProperties());
                
            }
            catch (Exception ex)
            {
                throw new RuntimeException
                    ("Property set stream \"" +
                     event.getPath() + event.getName() + "\": " + ex);
            }
            
        }

		private void addProperties(Map<String, String> metadata,
				Property[] properties) {
			String key = null;
			String value = null;
			for(int i=0; i < properties.length; i++){
				key = String.valueOf(properties[i].getID());
				value = properties[i].getValue().toString();
				metadata.put(key, value);
			}
			
		}

		private String translateDate(Date createDateTime) {
			return DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT, Locale.getDefault()).format(createDateTime);
		}
    }



}
